package org.hepeng.fabric.gateway.contract.proxy;

import org.hepeng.fabric.contract.api.ContractProvider;
import org.hepeng.fabric.contract.api.annotation.ContractAPI;
import org.hepeng.fabric.gateway.pool.FabricGatewayObject;
import org.hyperledger.fabric.client.Contract;
import org.hyperledger.fabric.client.Network;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author he peng
 * @date 2022/3/24
 */
public class FabricGatewayPoolContractProvider implements ContractProvider {

    @Override
    public Contract getContract(Object obj) {

        Contract contract = null;
        if (obj instanceof ContractAPI) {
            ContractAPI contractAPI = (ContractAPI) obj;
            String contractName = contractAPI.name();

            try {
                FabricGatewayObject fabricGatewayObject = FabricGatewayObjectHolder.current();
                contract = fabricGatewayObject.getContract(contractName);
                if (Objects.isNull(contract)) {
                    contract = initializeContract(fabricGatewayObject , contractAPI);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }

        }

        return contract;
    }

    private Contract initializeContract(FabricGatewayObject fabricGatewayObject , ContractAPI contractAPI) {

        String contractName = contractAPI.name();
        Network network = fabricGatewayObject.getNetwork(fabricGatewayObject.getKey().getChannel());
        Contract contract = network.getContract(contractAPI.chainCode() , contractName);

        if (Objects.nonNull(contract)) {
            Map<String, Contract> contractMap = fabricGatewayObject.getContracts();
            if (Objects.isNull(contractMap)) {
                contractMap = new HashMap<>();
            }
            contractMap.put(contractName , contract);
            fabricGatewayObject.setContracts(contractMap);
        }

        return contract;
    }
}
